using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using DowncastSystems.WhereWolf;

namespace WhereWolf
{
    //TODO: add "New Profile" support
    public partial class MainForm : Form
    {
        private About aboutForm;
        private ProfileManager manager = new ProfileManager(new TestProfileProvider());
        private Profile currentProfile;

        public MainForm()
        {
            InitializeComponent();
        }

        public Profile CurrentProfile
        {
            get { return currentProfile; }
            set
            {
                if (currentProfile != value)
                {
                    if (currentProfile != null)
                    {
                        this.CleanupProfile(currentProfile);
                    }
                    currentProfile = value;
                    if (currentProfile != null)
                    {
                        this.SetupProfile(currentProfile);
                    }
                }
            }
        }

        #region Event Handlers
        #region Event Handlers
        private void MainForm_Load(object sender, EventArgs e)
        {
            this.PopulateProfileList();
        }

        private void ProfileDropDown_SelectedIndexChanged(object sender, EventArgs e)
        {
            string selectedProfileName = (string)((ToolStripComboBox)sender).SelectedItem;
            this.CurrentProfile = manager.GetProfileByName(selectedProfileName);
        }

        private void CopyButton_Click(object sender, EventArgs e)
        {
            CopyFiles();
        }

        private void CancelCopyButton_Click(object sender, EventArgs e)
        {
            this.CurrentProfile.CancelCopy();
        }

        private void showErrorsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            splitContainer2.Panel2Collapsed = !((ToolStripMenuItem)sender).Checked;
        }
        #endregion

        #region Profile Event Handlers
        private void CopyStarting(Object sender, CancelEventArgs e)
        {
            e.Cancel = (MessageBox.Show(Properties.Resources.ConfirmationText, Properties.Resources.ConfirmationCaption, MessageBoxButtons.YesNo) == DialogResult.No);
        }

        private void CopyStarted(Object sender, EventArgs e)
        {
            this.toolStripProgressBar1.Visible = true;
            this.toolStripStatusLabel1.Visible = true;
            this.CancelCopyButton.Visible = true;
            this.CopyButton.Visible = false;
            this.ErrorListView.Items.Clear();

            this.toolStripProgressBar1.Value = 0;
            this.toolStripStatusLabel1.Text = string.Empty;
        }

        private void CopyProgress(Object sender, CopyProgressEventArgs e)
        {
            this.toolStripProgressBar1.Value = e.Percent;
            this.toolStripStatusLabel1.Text = e.FileInfo.FullName;
        }

        private void CopyCompleted(Object sender, EventArgs e)
        {
            CleanupCopying();
        }

        private void CopyCancelled(Object sender, EventArgs e)
        {
            CleanupCopying();
        }

        private void CopyError(Object sender, CopyErrorEventArgs e)
        {
            splitContainer2.Panel2Collapsed = false;
            showErrorsToolStripMenuItem.Checked = true;
            ErrorListView.Items.Add(e.FileInfo.FullName).SubItems.Add(e.Exception.Message);
        }
        #endregion
        #endregion

        #region Private Helpers
        private void CleanupProfile(Profile p)
        {
            p.CopyStarting -= this.CopyStarting;
            p.CopyStarted -= this.CopyStarted;
            p.CopyProgress -= this.CopyProgress;
            p.CopyComplete -= this.CopyCompleted;
            p.CopyCancelled -= this.CopyCancelled;
            p.CopyError -= this.CopyError;
        }

        private void SetupProfile(Profile p)
        {
            p.CopyStarting += this.CopyStarting;
            p.CopyStarted += this.CopyStarted;
            p.CopyProgress += this.CopyProgress;
            p.CopyComplete += this.CopyCompleted;
            p.CopyCancelled += this.CopyCancelled;
            p.CopyError += this.CopyError;

            this.PopulateProfileDetails(p);
        }

        private void PopulateProfileDetails(Profile p)
        {
            this.PopulateListView(this.FileListView, p.SourceFiles, delegate(FileInfo i)
            {
                return new ListViewItem(new string[] { i.Name, i.DirectoryName });
            });

            this.PopulateListView(this.FolderListView, p.TargetFolders, delegate(DirectoryInfo i)
            {
                return new ListViewItem(i.FullName);
            });
        }

        private void CleanupCopying()
        {
            this.toolStripProgressBar1.Visible = false;
            this.toolStripStatusLabel1.Visible = false;
            this.CancelCopyButton.Visible = false;
            this.CopyButton.Visible = true;
        }

        private void PopulateListView<T>(ListView listView, ICollection<T> source, Converter<T, ListViewItem> converter)
        {
            listView.BeginUpdate();
            listView.Items.Clear();
            if (source.Count > 0)
            {
                System.Collections.Generic.List<T> sourceList = new List<T>(source);
                listView.Items.AddRange(sourceList.ConvertAll(converter).ToArray());
            }
            listView.EndUpdate();
        }

        private void PopulateProfileList()
        {
            List<Profile> profiles = new List<Profile>(manager.GetAllProfiles());
            List<string> profileNames = profiles.ConvertAll<string>(delegate(Profile p) { return p.Name; });
            this.ProfileDropDown.Items.AddRange(profileNames.ToArray());
        }

        private void AddFolder()
        {
            if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                this.CurrentProfile.AddFolder(this.folderBrowserDialog1.SelectedPath);
                this.PopulateProfileDetails(this.CurrentProfile);
            }
        }

        private void AddFiles()
        {
            if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                new List<string>(this.openFileDialog1.FileNames).ForEach(this.CurrentProfile.AddFile);
                this.PopulateProfileDetails(this.CurrentProfile);
            }
        }

        private void CopyFiles()
        {
            Profile p = this.CurrentProfile;
            if (p != null)
            {
                p.CopySourceFilesToTargetFolders();
            }
        }

        private void RemoveFolders()
        {
            foreach (ListViewItem item in this.FolderListView.SelectedItems)
            {
                this.CurrentProfile.RemoveFolder(item.Text);
            }
            this.PopulateProfileDetails(this.CurrentProfile);
        }

        private void RemoveFiles()
        {
            foreach (ListViewItem item in this.FileListView.SelectedItems)
            {
                this.CurrentProfile.RemoveFile(item.Text);
            }
            this.PopulateProfileDetails(this.CurrentProfile);
        }
        #endregion

        private void AddFolderButton_Click(object sender, EventArgs e)
        {
            this.AddFolder();
        }

        private void AddFilesButton_Click(object sender, EventArgs e)
        {
            AddFiles();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (aboutForm == null)
            {
                aboutForm = new About();
            }
            aboutForm.ShowDialog();
        }

        private void saveCurrentProfileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.manager.SaveProfile(this.CurrentProfile);
        }

        private void deleteCurrentProfileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.manager.DeleteProfile(this.CurrentProfile);
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void addFilesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.AddFiles();
        }

        private void addFolderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.AddFolder();
        }

        private void copyFilesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.CopyFiles();
        }

        private void RemoveFolderMenuItem_Click(object sender, EventArgs e)
        {
            this.RemoveFolders();
        }

        private void AddFolderMenuItem_Click(object sender, EventArgs e)
        {
            this.AddFolder();
        }

        private void RemoveFilesMenuItem_Click(object sender, EventArgs e)
        {
            this.RemoveFiles();
        }

        private void AddFilesMenuItem_Click(object sender, EventArgs e)
        {
            this.AddFiles();
        }

        private void FolderListView_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                this.RemoveFolders();
            }
        }

        private void FileListView_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                this.RemoveFiles();
            }
        }

        private void newProfileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            throw new NotImplementedException("This feature isn't implemented yet.");
        }
    }
}